use actix_web::{HttpRequest, HttpResponse, web};
use serde::Serialize;

use common::error::MyError;
use common::header::Authorization;
use common::page::{BasePage, PageResult};
use common::r::JsonResult;
use service::base::BaseService;
use service::manager::base::BaseManager;

/// 抽象增删改查接口控制层
/// Unlike [`SERVICE`] SERVICE 服务类 需要继承  [`BaseService`])
/// Unlike [`ID`] ID 实体模型id类型
/// Unlike [`ENTITY`] 实体模型 当前版本作为接口返回值
/// Unlike [`PAGE`] 抽象分页参数对象
/// Unlike [`CREATE`] 添加数据的入参对象
/// Unlike [`UPDATE`] 更新数据的入参对象
/// Unlike [`MANAGER`] 数据库实际操作对象 需要实现 [`BaseManager`]
#[allow(async_fn_in_trait)]
pub trait BaseController<SERVICE, ID, ENTITY, PAGE, CREATE, UPDATE, MANAGER>
where
    SERVICE: BaseService<ID, ENTITY, PAGE, CREATE, UPDATE, MANAGER>,
    ID: Serialize,
    ENTITY: Serialize,
    PAGE: Serialize + BasePage,
    CREATE: Serialize + Clone,
    UPDATE: Serialize + Clone,
    MANAGER: BaseManager<ID, ENTITY, PAGE, CREATE, UPDATE>,
{
    async fn list(
        req: HttpRequest,
        authorization: web::Header<Authorization>,
    ) -> Result<HttpResponse, MyError> {
        Ok(HttpResponse::Ok().json(JsonResult::<Vec<ENTITY>>::ok(
            SERVICE::list(&req, authorization).await?,
        )))
    }

    async fn page(
        form: web::Json<PAGE>,
        req: HttpRequest,
        authorization: web::Header<Authorization>,
    ) -> Result<HttpResponse, MyError> {
        Ok(
            HttpResponse::Ok().json(JsonResult::<PageResult<ENTITY>>::ok(
                SERVICE::page(form.into_inner(), &req, authorization).await?,
            )),
        )
    }

    async fn info(
        params: web::Path<ID>,
        req: HttpRequest,
        authorization: web::Header<Authorization>,
    ) -> Result<HttpResponse, MyError> {
        Ok(HttpResponse::Ok().json(JsonResult::<ENTITY>::ok(
            SERVICE::info(params.into_inner(), &req, authorization).await?,
        )))
    }

    async fn add(
        form: web::Json<CREATE>,
        req: HttpRequest,
        authorization: web::Header<Authorization>,
    ) -> Result<HttpResponse, MyError> {
        Ok(HttpResponse::Ok().json(JsonResult::<ID>::ok(
            SERVICE::add(form.into_inner(), &req, authorization).await?,
        )))
    }

    async fn update(
        form: web::Json<UPDATE>,
        req: HttpRequest,
        authorization: web::Header<Authorization>,
    ) -> Result<HttpResponse, MyError> {
        Ok(HttpResponse::Ok().json(JsonResult::<ID>::ok(
            SERVICE::update(form.into_inner(), &req, authorization).await?,
        )))
    }

    async fn delete(
        params: web::Path<ID>,
        req: HttpRequest,
        authorization: web::Header<Authorization>,
    ) -> Result<HttpResponse, MyError> {
        Ok(HttpResponse::Ok().json(JsonResult::<bool>::ok(
            SERVICE::delete(params.into_inner(), &req, authorization).await?,
        )))
    }
}
